from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from app.db.session import get_db
from app.crud.crud_post import post_crud, publish_job_crud
from app.schemas.post import PublishJobCreate, PublishJobResponse
from app.xxl_job.xxl_api import xxl_job_api
from app.xxl_job.handler import list_handlers

router = APIRouter()


@router.post("/", response_model=PublishJobResponse)
def create_publish_job(
    job_in: PublishJobCreate,
    db: Session = Depends(get_db)
):
    """创建发布任务"""
    # 检查帖子是否存在
    post = post_crud.get(db=db, id=job_in.post_id)
    if not post:
        raise HTTPException(status_code=404, detail="Post not found")
    
    # 检查是否已经有发布任务
    existing_job = publish_job_crud.get_by_post_id(db=db, post_id=job_in.post_id)
    if existing_job:
        raise HTTPException(
            status_code=400, 
            detail=f"Publish job already exists for post {job_in.post_id}"
        )
    
    # 创建本地任务记录
    job = publish_job_crud.create(db=db, obj_in=job_in)
    
    try:
        # 在XXL-Job中创建任务
        xxl_job_info = {
            'jobDesc': job_in.job_desc,
            'scheduleConf': job_in.job_cron,
            'executorParam': str(job_in.post_id),  # 传递post_id作为参数
            'executorHandler': 'publishPostHandler'
        }
        
        xxl_job_id = xxl_job_api.add_job(xxl_job_info)
        
        if xxl_job_id:
            # 更新本地记录的XXL-Job ID
            publish_job_crud.update_xxl_job_id(db=db, job_id=job.id, xxl_job_id=xxl_job_id)
            job.xxl_job_id = xxl_job_id
        else:
            # 如果XXL-Job创建失败，删除本地记录
            publish_job_crud.delete(db=db, id=job.id)
            raise HTTPException(
                status_code=500,
                detail="Failed to create job in XXL-Job scheduler"
            )
    
    except Exception as e:
        # 清理本地记录
        publish_job_crud.delete(db=db, id=job.id)
        raise HTTPException(
            status_code=500,
            detail=f"Failed to create publish job: {str(e)}"
        )
    
    return job


@router.get("/", response_model=List[PublishJobResponse])
def get_publish_jobs(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    """获取发布任务列表"""
    jobs = publish_job_crud.get_multi(db=db, skip=skip, limit=limit)
    return jobs


@router.get("/{job_id}", response_model=PublishJobResponse)
def get_publish_job(
    job_id: int,
    db: Session = Depends(get_db)
):
    """获取单个发布任务"""
    job = publish_job_crud.get(db=db, id=job_id)
    if not job:
        raise HTTPException(status_code=404, detail="Publish job not found")
    return job


@router.post("/{job_id}/start")
def start_job(
    job_id: int,
    db: Session = Depends(get_db)
):
    """启动发布任务"""
    job = publish_job_crud.get(db=db, id=job_id)
    if not job:
        raise HTTPException(status_code=404, detail="Publish job not found")
    
    if not job.xxl_job_id:
        raise HTTPException(
            status_code=400,
            detail="Job not properly configured in XXL-Job scheduler"
        )
    
    try:
        success = xxl_job_api.start_job(job.xxl_job_id)
        
        if success:
            # 更新本地状态
            publish_job_crud.update_status(db=db, job_id=job_id, status=1)  # 1-运行中
            return {"message": f"Job {job_id} started successfully"}
        else:
            raise HTTPException(
                status_code=500,
                detail="Failed to start job in XXL-Job scheduler"
            )
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to start job: {str(e)}"
        )


@router.post("/{job_id}/stop")
def stop_job(
    job_id: int,
    db: Session = Depends(get_db)
):
    """停止发布任务"""
    job = publish_job_crud.get(db=db, id=job_id)
    if not job:
        raise HTTPException(status_code=404, detail="Publish job not found")
    
    if not job.xxl_job_id:
        raise HTTPException(
            status_code=400,
            detail="Job not properly configured in XXL-Job scheduler"
        )
    
    try:
        success = xxl_job_api.stop_job(job.xxl_job_id)
        
        if success:
            # 更新本地状态
            publish_job_crud.update_status(db=db, job_id=job_id, status=2)  # 2-已停止
            return {"message": f"Job {job_id} stopped successfully"}
        else:
            raise HTTPException(
                status_code=500,
                detail="Failed to stop job in XXL-Job scheduler"
            )
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to stop job: {str(e)}"
        )


@router.delete("/{job_id}")
def delete_job(
    job_id: int,
    db: Session = Depends(get_db)
):
    """删除发布任务"""
    job = publish_job_crud.get(db=db, id=job_id)
    if not job:
        raise HTTPException(status_code=404, detail="Publish job not found")
    
    try:
        # 先从XXL-Job中删除
        if job.xxl_job_id:
            xxl_job_api.remove_job(job.xxl_job_id)
        
        # 删除本地记录
        publish_job_crud.delete(db=db, id=job_id)
        
        return {"message": f"Job {job_id} deleted successfully"}
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to delete job: {str(e)}"
        )


@router.get("/{job_id}/info")
def get_job_info(
    job_id: int,
    db: Session = Depends(get_db)
):
    """获取任务在XXL-Job中的详细信息"""
    job = publish_job_crud.get(db=db, id=job_id)
    if not job:
        raise HTTPException(status_code=404, detail="Publish job not found")
    
    if not job.xxl_job_id:
        raise HTTPException(
            status_code=400,
            detail="Job not properly configured in XXL-Job scheduler"
        )
    
    try:
        xxl_job_info = xxl_job_api.get_job_info(job.xxl_job_id)
        
        if xxl_job_info:
            return {
                "local_job": {
                    "id": job.id,
                    "post_id": job.post_id,
                    "status": job.status,
                    "created_at": job.created_at,
                    "updated_at": job.updated_at
                },
                "xxl_job_info": xxl_job_info
            }
        else:
            raise HTTPException(
                status_code=404,
                detail="Job not found in XXL-Job scheduler"
            )
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to get job info: {str(e)}"
        )


@router.post("/{job_id}/execute-now")
async def execute_job_now(
    job_id: int,
    db: Session = Depends(get_db)
):
    """立即执行发布任务（不通过调度）"""
    job = publish_job_crud.get(db=db, id=job_id)
    if not job:
        raise HTTPException(status_code=404, detail="Publish job not found")
    
    try:
        # 直接调用handler执行任务
        from app.xxl_job.handler import publish_post_handler
        
        result = await publish_post_handler(str(job.post_id))
        
        return {
            "message": "Job executed immediately",
            "job_id": job_id,
            "execution_result": result
        }
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to execute job: {str(e)}"
        )


@router.get("/handlers/list")
def list_job_handlers():
    """列出所有可用的任务处理器"""
    handlers = list_handlers()
    return {
        "handlers": handlers,
        "count": len(handlers)
    }


@router.post("/test-xxl-connection")
def test_xxl_connection():
    """测试XXL-Job连接"""
    try:
        success = xxl_job_api.login()
        
        if success:
            # 尝试获取任务列表
            jobs = xxl_job_api.get_job_list()
            return {
                "success": True,
                "message": "XXL-Job connection successful",
                "job_count": len(jobs)
            }
        else:
            return {
                "success": False,
                "message": "Failed to login to XXL-Job"
            }
    
    except Exception as e:
        return {
            "success": False,
            "message": f"XXL-Job connection failed: {str(e)}"
        }


@router.post("/sync-status")
def sync_job_status(
    db: Session = Depends(get_db)
):
    """同步本地任务状态与XXL-Job"""
    try:
        # 获取所有本地任务
        local_jobs = publish_job_crud.get_multi(db=db, skip=0, limit=1000)
        
        # 获取XXL-Job中的任务列表
        xxl_jobs = xxl_job_api.get_job_list()
        xxl_job_dict = {job['id']: job for job in xxl_jobs}
        
        updated_count = 0
        
        for local_job in local_jobs:
            if local_job.xxl_job_id and local_job.xxl_job_id in xxl_job_dict:
                xxl_job = xxl_job_dict[local_job.xxl_job_id]
                
                # 根据XXL-Job状态更新本地状态
                # triggerStatus: 0-停止，1-运行
                xxl_status = xxl_job.get('triggerStatus', 0)
                
                if xxl_status == 1 and local_job.status != 1:
                    publish_job_crud.update_status(db=db, job_id=local_job.id, status=1)
                    updated_count += 1
                elif xxl_status == 0 and local_job.status == 1:
                    publish_job_crud.update_status(db=db, job_id=local_job.id, status=2)
                    updated_count += 1
        
        return {
            "message": "Status synchronization completed",
            "updated_count": updated_count,
            "total_local_jobs": len(local_jobs),
            "total_xxl_jobs": len(xxl_jobs)
        }
    
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to sync job status: {str(e)}"
        )